#include "cubeshader.h"
#include <math.h>

CubeShader::CubeShader(QObject *parent)
    :BaseShader(parent)
{
    m_file_vert = ":/triangles.vert";
    m_file_frag = ":/triangles.frag";
}

void CubeShader::initializeGL()
{
    BaseShader::initializeGL();

    aPos = m_program->attributeLocation("aPos");
    aNormal = m_program->attributeLocation("aNormal");
    aTexCoords = m_program->attributeLocation("aTexCoords");

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(aPos, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), BUFFER_OFFSET(0));
    glVertexAttribPointer(aNormal, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), BUFFER_OFFSET(3 * sizeof(GLfloat)));
    glVertexAttribPointer(aTexCoords, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), BUFFER_OFFSET(6 * sizeof(GLfloat)));

    glEnableVertexAttribArray(aPos);
    glEnableVertexAttribArray(aNormal);
    glEnableVertexAttribArray(aTexCoords);

    //生成纹理
    m_texture = new QOpenGLTexture(QImage(":/container.png").mirrored());
    m_texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear);
    m_texture->setMagnificationFilter(QOpenGLTexture::Linear);

    m_texture2 = new QOpenGLTexture(QImage(":/container_specular.png").mirrored());
    m_texture2->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear);
    m_texture2->setMagnificationFilter(QOpenGLTexture::Linear);
}

void CubeShader::paintGL()
{
    //显示10个立方体
    QVector3D cubePositions[] = {
      QVector3D( 0.0f,  0.0f,  0.0f),
      QVector3D( 2.0f,  5.0f, -15.0f),
      QVector3D(-1.5f, -2.2f, -2.5f),
      QVector3D(-3.8f, -2.0f, -12.3f),
      QVector3D( 2.4f, -0.4f, -3.5f),
      QVector3D(-1.7f,  3.0f, -7.5f),
      QVector3D( 1.3f, -2.0f, -2.5f),
      QVector3D( 1.5f,  2.0f, -2.5f),
      QVector3D( 1.5f,  0.2f, -1.5f),
      QVector3D(-1.3f,  1.0f, -1.5f)
    };

    m_program->bind();

    m_texture->bind(0);
    m_texture2->bind(1);

    m_program->setUniformValue("projection", projection);
    m_program->setUniformValue("view", view);
//    m_program->setUniformValue("model", model);

    m_program->setUniformValue("material.diffuse", 0);
    m_program->setUniformValue("material.specular", 1);
    m_program->setUniformValue("material.shininess", 32.0f);

    m_program->setUniformValue("viewPos", viewPos);

    m_program->setUniformValue("light.ambient", lightColor * QVector3D(0.2f, 0.2f, 0.2f));
    m_program->setUniformValue("light.diffuse", lightColor * QVector3D(0.5f, 0.5f, 0.5f));
    m_program->setUniformValue("light.specular", QVector3D(1.0f, 1.0f, 1.0f));

    m_program->setUniformValue("light.position", pos); // 灯位置

    m_program->setUniformValue("light.constant", pos); //衰减系数
    m_program->setUniformValue("light.direction", dir);
    m_program->setUniformValue("light.cutOff", (GLfloat)cos(12.5f/180.0f * M_PI));
    m_program->setUniformValue("light.outerCutOff", (GLfloat)cos(17.5f/180.0f * M_PI));

    for(unsigned int i = 0; i< 10; i++)
    {
        QMatrix4x4 model;
        model.translate(cubePositions[i]);
        float angle = 20.0f * i;
        model.rotate(angle, QVector3D(0.5f, 1.0f, 0.0f));

        m_program->setUniformValue("model", model);

        glDrawArrays(GL_TRIANGLES, 0, 36);
    }

    m_texture->release();
    m_texture2->release();
    m_program->release();
}
